#include <iostream>
#include <memory>

class Fruit
{
public:
    virtual void name() = 0;
};

class Apple : public Fruit
{
public:
    Apple()
    {
    }
    void name() override
    {
        std::cout << "我是一个苹果\n";
    }
};

class Banana : public Fruit
{
public:
    Banana()
    {
    }
    void name() override
    {
        std::cout << "我是一个香蕉\n";
    }
};

class Animal
{
public:
    virtual void name() = 0;
};

class Lamp : public Animal
{
public:
    void name() override
    {
        std::cout << "我是山羊" << std::endl;
    }
};

class Dog : public Animal
{
public:
    void name() override
    {
        std::cout << "我是小狗" << std::endl;
    }
};

class Factory
{
public:
    virtual std::shared_ptr<Fruit> getFruit(const std::string &name) = 0;
    virtual std::shared_ptr<Fruit> getAnimal(const std::string &name) = 0;
};

class AnimalFactoy : public Factory
{
public:
    std::shared_ptr<Animal> getFruit(const std::string &name)
    {
        return std::shared_ptr<Animal>();
    }
    std::shared_ptr<Fruit> getAnimal(const std::string &name)
    {
        if (name == "小狗")
        {
            return std::make_shared<Dog>();
        }
        else
        {
            return std::make_shared<Lamp>();
        }
    }
};

class FruitFactory : public Factory
{
public:
    std::shared_ptr<Animal> getAnimal(const std::string &name)
    {
        return std::shared_ptr<Animal>();
    }
    std::shared_ptr<Fruit> getFruit(const std::string &name)
    {
        if (name == "苹果")
        {
            return std::make_shared<Apple>();
        }
        else
        {
            return std::make_shared<Banana>();
        }
    }
};

//---- 简单工产模式 ------------

//  class FruitFactory
//  {
//  public:
//      static std::shared_ptr<Fruit> create(const std::string &name)
//      {
//          if (name == "苹果")
//          {
//              return std::make_shared<Apple>();
//          }
//          else
//          {
//              return std::make_shared<Banana>();
//          }
//      }
//  };
// int main()
// {
//     std::shared_ptr<Fruit> fruit = FruitFactory::create("苹果");
//     fruit->name();
//     fruit = FruitFactory::create("香蕉");
//     fruit->name();

//     return 0;
// }
//----------------

//------ 工厂方法模式 -------
class FruitFactory
{
public:
    virtual std::shared_ptr<Fruit> create() = 0;
};

class AppleFactory : public FruitFactory
{
public:
    std::shared_ptr<Fruit> create() override
    {
        return std::make_shared<Apple>();
    }
};

class BananaFactory : public FruitFactory
{
public:
    std::shared_ptr<Fruit> create() override
    {
        return std::make_shared<Banana>();
    }
};
int main()
{
    std::shared_ptr<FruitFactory> ff(new AppleFactory());
    std::shared_ptr<Fruit> fruit = ff->create();
    fruit->name();
    ff.reset(new BananaFactory());
    fruit = ff->create();
    fruit->name();
}